﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Thrift;
using Thrift.Server;
using Thrift.Transport;
using XXF.BaseService.ServiceCenter.Service.Protocol;
using XXF.BaseService.ServiceCenter.Service.Provider;
using XXF.BaseService.ServiceCenter.Service.Visitor;
using XXF.BaseService.ServiceCenter.SystemRuntime;

namespace XXF.BaseService.ServiceCenter.Service.Server
{
    /// <summary>
    /// Thrift服务类
    /// </summary>
    public class ThriftServer : BaseServer
    {
        private TServer server;
        private TradeServerEventHandler serverevent;

        public override EnumServiceType ServiceType { get { return EnumServiceType.Thrift; } }

        public ThriftServer()
        {
        }

        public override void Run<T>(int port, Protocol.ServiceProtocal protocal, ServiceContext context, Action successCallAction)
        {
            Type thrifttype = null;
            try
            {
                //自身协议转Thrift协议
                ProtocolsToThrift t = new ProtocolsToThrift();
                thrifttype = t.ToType(protocal, typeof(T).Namespace);
            }
            catch (Exception exp)
            {
                throw new ServiceCenterException("自定义协议生成Thrift协议时出错", exp);
            }
            Type serviceproxytype = null;
            try
            {
                //动态代理服务类
                DynamicServiceProxy proxy = new DynamicServiceProxy();
                serviceproxytype = proxy.To(thrifttype, typeof(T), protocal);
            }
            catch (Exception exp)
            {
                throw new ServiceCenterException("生成Thrift动态代理时出错", exp);
            }
            try
            {
                //开启Thrift服务
                TServerSocket serverTransport = new TServerSocket(port, 0, true);
                var serviceproxy = Activator.CreateInstance(serviceproxytype);
                this.ServerVisitor = (IVisitor)serviceproxy;
                var processor = (TProcessor)Activator.CreateInstance(thrifttype.Assembly.GetType(thrifttype.FullName + "+Processor"), new object[] { serviceproxy });
                //server = new TThreadPoolServer(processor, serverTransport);
                server = new TThreadedServer(processor, serverTransport, LogDelegate);
                serverevent = new TradeServerEventHandler(successCallAction);
                server.setEventHandler(serverevent);
                server.Serve();
            }
            catch (Exception exp)
            {
                throw new ServiceCenterException("打开Thrift服务时出错", exp);
            }
        }

        /// <summary>
        /// Log
        /// </summary>
        /// <param name="s"></param>
        protected static void LogDelegate(string s)
        {

        }

        public override void Stop()
        {
            if (server != null)
            {
                server.Stop();
                server = null;
            }
        }

        public override void Restart()
        {
            if (server != null)
            {
                try
                {
                    server.Stop();
                    server = null;
                }
                catch
                { }
            }
        }
    }

    /// <summary>
    /// Thrift服务状态回调
    /// </summary>
    public class TradeServerEventHandler : TServerEventHandler
    {

        private Action callction;
        public TradeServerEventHandler(Action successCallAction)
        {
            callction = successCallAction;
        }
        public void preServe()
        {
            callction.Invoke();
        }
        public Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
        {
            return null;
        }
        public void deleteContext(Object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
        {
        }
        public void processContext(Object serverContext, Thrift.Transport.TTransport transport)
        {

        }
    };
}
